/*********************************************************************
Copyright 2011 Chris Gardner

This file is part of CardRoulette.

CardRoulette is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

CardRoulette is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with CardRoulette.  If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

using FreestyleCoding.CardLib;
using System.Text;

namespace CardRoulette {
	/// <summary>
	/// This is the main type for your game
	/// </summary>
	public class Game1 : Microsoft.Xna.Framework.Game {
		GraphicsDeviceManager graphics;
		SpriteBatch spriteBatch;

		static bool _Pressed;

		SpriteFont _Font;

		IPlayingCard _Card;

		IDeck<IPlayingCard> _Deck;
		IDeck<IPlayingCard> _Discard;

		public Game1() {
			graphics = new GraphicsDeviceManager( this );
			Content.RootDirectory = "Content";
		}

		/// <summary>
		/// Allows the game to perform any initialization it needs to before starting to run.
		/// This is where it can query for any required services and load any non-graphic
		/// related content.  Calling base.Initialize will enumerate through any components
		/// and initialize them as well.
		/// </summary>
		protected override void Initialize() {
			// TODO: Add your initialization logic here

			_Pressed = false;

			_Deck = PokerDeck.New();
			
			_Discard = PokerDeck.New();
			while( _Discard.HasCards ) _Discard.Draw();

			base.Initialize();
		}

		/// <summary>
		/// LoadContent will be called once per game and is the place to load
		/// all of your content.
		/// </summary>
		protected override void LoadContent() {
			// Create a new SpriteBatch, which can be used to draw textures.
			spriteBatch = new SpriteBatch( GraphicsDevice );

			// TODO: use this.Content to load your game content here
			_Font = Content.Load<SpriteFont>( "Font" );
		}

		/// <summary>
		/// UnloadContent will be called once per game and is the place to unload
		/// all content.
		/// </summary>
		protected override void UnloadContent() {
			// TODO: Unload any non ContentManager content here
		}

		/// <summary>
		/// Allows the game to run logic such as updating the world,
		/// checking for collisions, gathering input, and playing audio.
		/// </summary>
		/// <param name="gameTime">Provides a snapshot of timing values.</param>
		protected override void Update( GameTime gameTime ) {
			// Allows the game to exit
			GamePadState _State = GamePad.GetState( PlayerIndex.One );

			if( _State.Buttons.Back == ButtonState.Pressed )
				this.Exit();

			if( _State.Buttons.A == ButtonState.Pressed ) {
				if( !_Pressed ) {
					_Pressed = true;

					if( _Deck.HasCards ) {
						if( _Card != null ) {
							_Discard.Insert( _Card );
						}

						_Card = _Deck.Draw();
						Statistics.Update( _Card );
					} else {
						_Deck.Merge( _Discard );
						_Deck.Shuffle();

						Statistics.Calculate( _Deck );
					}
				}
			} else {
				_Pressed = false;
			}

			base.Update( gameTime );
		}

		/// <summary>
		/// This is called when the game should draw itself.
		/// </summary>
		/// <param name="gameTime">Provides a snapshot of timing values.</param>
		protected override void Draw( GameTime gameTime ) {
			GraphicsDevice.Clear( Color.Black );
			spriteBatch.Begin();

			Vector2 _Size;
			StringBuilder _Builder = new StringBuilder();
			foreach( IPlayingCard l_Card in _Deck ) {
				_Builder.AppendLine( l_Card.ToString() );
			}
			spriteBatch.DrawString( _Font, _Builder.ToString(), new Vector2( 20, 20 ), Color.Red );

			if( _Card != null ) {
				_Builder.Remove( 0, _Builder.Length );
				_Builder.AppendLine( _Card.ToString() );

				_Size = _Font.MeasureString( _Builder.ToString() );

				spriteBatch.DrawString( _Font, _Builder.ToString(), new Vector2( ( GraphicsDevice.Viewport.Width / 2 ) - ( _Size.X / 2 ), 20 ), Color.White );
			}

			_Builder.Remove( 0, _Builder.Length );
			foreach( IPlayingCard l_Card in _Discard ) {
				_Builder.AppendLine( l_Card.ToString() );
			}

			_Size = _Font.MeasureString( _Builder.ToString() );
			spriteBatch.DrawString( _Font, _Builder.ToString(), new Vector2( GraphicsDevice.Viewport.Width - _Size.X - 20, 20 ), Color.Green );

			spriteBatch.End();
			base.Draw( gameTime );
		}
	}
}
